﻿using System;
using System.Collections.Generic;
using SdmxMl.Common;
using System.Windows.Forms;

namespace SdmxMl.UC
{
    public enum SearchType
    {
        Exact,
        Start,
        End,
        Any
    }

    /// <summary>
    /// Class to operate quick search on Tree nodes. 
    /// (ID or Name of Object implementing ISearchName in node Tag)
    /// </summary>
    public class Search
    {
        public static bool MatchPattern(SearchType st, string pattern, string target)
        {
            bool match = false;
            switch (st)
            {
                case SearchType.Any:
                    if (target.IndexOf(pattern, StringComparison.CurrentCultureIgnoreCase) >= 0)
                        match = true;
                    break;

                case SearchType.Start:
                    if (target.StartsWith(pattern, StringComparison.CurrentCultureIgnoreCase))
                        match = true;
                    break;

                case SearchType.End:
                    if (target.EndsWith(pattern, StringComparison.CurrentCultureIgnoreCase))
                        match = true;
                    break;

                case (int)SearchType.Exact:
                    if (string.Compare(target, pattern, true) == 0)
                        match = true;
                    break;
            }

            return match;
        }

        public static bool MatchSearch(SearchType st, bool onCode, TreeNode node, string pattern)
        {
            bool match = false;
            ISearchIdName aBO = node.Tag as ISearchIdName;
            if (aBO == null)
                aBO = new DefaultIdName(node);

            if (onCode)
                match = MatchPattern(st, pattern, aBO.Id);
            else 
            {
                string name = aBO.Name.ToString();
                match = MatchPattern(st, pattern, name);
            }

            return match;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="list"></param>
        /// <param name="st"></param>
        /// <param name="onCode"></param>
        /// <param name="node"></param>
        /// <param name="langNdx"></param>
        /// <param name="pattern"></param>
        public static void Process(List<TreeNode> list, SearchType st, bool onCode, TreeNode node, TreeView tv, string pattern)
        {
            if (node != null)
            {
                if (MatchSearch(st, onCode, node, pattern))
                    list.Add(node);
                foreach (TreeNode n in node.Nodes)
                    Process(list, st, onCode, n, tv, pattern);
            }
            else if (tv != null)
            {
                foreach (TreeNode n in tv.Nodes)
                    Process(list, st, onCode, n, tv, pattern);
            }
        }

        /// <summary> Define search type and update search text.</summary>
        /// <param name="text"></param>
        /// <returns>the updated pattern</returns>
        public static SearchType DefinePattern(ref string text)
        {
            string pattern = text.Trim();
            SearchType st = SearchType.Any;
            if (pattern.IndexOf('*') < 0)
                st = SearchType.Exact;
            else if (pattern.Length > 1 && pattern[0] == '*' && pattern[pattern.Length - 1] != '*')
                st = SearchType.End;
            else if (pattern.Length > 1 && pattern[0] != '*' && pattern[pattern.Length - 1] == '*')
                st = SearchType.Start;
            pattern = pattern.Replace("*", "");

            text = pattern;
            return st;
        }
    }

    #region Class DefaultIdName

    /// <summary>
    /// Helper class for tree node content that is not part of ISearchName interface
    /// </summary>
    public class DefaultIdName : ISearchIdName
    {
        public DefaultIdName(TreeNode node)
        {
            if (node != null && node.Text != null)
            {
                string n = node.Text;

                // Assumes Id and name separated by character '-'
                int ndx = n.IndexOf('-');
                if (ndx > 0 && n.Length > ndx + 1)
                {
                    _id = n.Substring(0, ndx).Trim();
                    n = n.Substring(ndx + 1, n.Length - (ndx + 1)).Trim();
                }
                else
                    _id = n;

                _name = new MultiLang();
                _name.UpdateForLanguage(LangSupport.CurLang, n);
            }
            else
            {
                _name = new MultiLang();
                _id = string.Empty;
            }
        }

        #region ISearchIdName Members

        private MultiLang _name;
        public MultiLang Name
        {
            get { return _name; }
        }

        private string _id;
        public string Id
        {
            get
            {
                return _id;
            }
            set
            {
                _id = value; ;
            }
        }

        #endregion
    }
    #endregion
}
